home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
amok_lha
/
amok49.lha
/
RCT
/
RCT.dok
< prev
next >
Wrap
Text File
|
1993-08-15
|
6KB
|
142 lines
(*
:Program. RCT.mod
:Contents. RCT exports functions to use RCT-generated
:Contents. c-source-code from Amiga-Oberon
:Author. Volker Rudolph
:Address. Lettow-Vorbeck-Str. 11 / 6750 Kaiserslautern 26
:Phone. 06301/8566
:Copyright. Freeware
:Language. Oberon / Assembler
:Translator. Oberon V1.17.1 / A68k (Freeware)
:History. Version 1.0 - first public release
:Bugs. No known bugs.
*)
Es gibt mittlerweile einige Tools mit denen man komfortabel Intuition-
Objekte wie Screens, Windows, Requester und Menüs erzeugen kann, z.B.
Power-Windows und RCT. Leider generieren diese Programme nur
Quelltexte für C oder Assembler, nicht aber für Oberon. Glücklicher-
weise bietet Amiga-Oberon aber die Möglichkeit, Programmteile aus
anderen Programmiersprachen zu Oberon-Modulen dazuzulinken. Da ich
stolzer Besitzer des RCT (Resource-Construction-Tool) bin, habe ich
mich einmal damit beschäftigt, RCT-generierte C-Quelltexte in Oberon
zu verwenden. Es gab dabei einige kleine Probleme, die ich mit dem
Modul RCT gelöst habe. Ich habe mich für C entschieden, da die
Quelltexte kürzer und klarer aufgebaut sind als Assembler-Quelltexte.
Als C-Compiler habe ich den DICE von Matt Dillon benutzt (Shareware).
Allgemeines:
Das RCT erzeugt C-Quelltexte, die aus vorinitialisierten Records und
Arrays, aber auch aus Prozeduren bestehen. Mit den vorinitiali-
sierten Daten gibt es keine Probleme, aber Prozeduren werden in C
etwas anders aufgerufen als in Oberon. Der Unterschied liegt in der
Parameterübergabe und in der Bereinigung des Stacks nach dem
Prozeduraufruf. In Oberon werden die Argumente eines Prozedur-
aufrufs von links nach rechts auf den Stack gelegt, das heißt das
erste Argument zuerst, dann das nächste usw. . In C ist es genau
andersherum, hier wird das letzte Argument zuerst auf den Stack
gelegt. Dieser Unterschied interessiert hier aber nicht, da die von
RCT erzeugten Prozeduren alle nur ein Argument haben. Wesentlich
störender ist der Unterschied in der Stackbereinigung. In Oberon
wird der Stackbereich der für die Argumente der Prozedur gebraucht
wurde, von der Prozedur selbst wieder freigegeben, in C wird das von
der aufrufenden Funktion erledigt. Wenn man also eine C-Prozedur
direkt aufrufen würde, würde der Stack gründlich durcheinander
geraten und das hätte dann natürlich den Programmabsturz zur Folge.
Dieses Problem löst die Funktion CCall() aus dem Modul RCT. Ihr
übergibt man die C-Funktion und das Funktions-Argument und CCall
kümmert sich dann um den Stack. Ein anderes Problem beim RCT sind
Image-Strukturen. Die Bilddaten für die Images müssen natürlich im
Chip-Memory stehen, aber RCT kümmert das überhaupt nicht. Die
Bilddaten (im C-Source 'reqimgbitblk') werden als normale Konstanten
definiert und dann auch mit den anderen Daten ins Fast-Memory
geladen (falls vorhanden). Es ist natürlich keine Lösung vor dem
Programmstart jedes mal NoFastMem zu starten, deshalb gibt es die
Prozedur ImagesToChip, die diese Image-Strukturen kopiert.
33mProzedur-Beschreibungen:31m
Aufruf einer C-Funktion:
PROCEDURE CCall(cProc:CProcType;arg:LONGINT):LONGINT;
Eingabe:
cProc: C-Funktion (siehe Beispiel Req.mod)
arg: Argument der C-Funktion
Returnwert: Returnwert der C-Funktion
PROCEDURE ImagesToChip*(images:I.ImagePtr;imageNum:INTEGER):BOOLEAN;
Eingabe:
images: Pointer auf die Image-Records im C-Quelltext
imageNum: Anzahl der Image-Records
Returnwert: FALSE, falls nicht genug Chip-Memory frei war.
Wie man nun RCT-generierte Quelltexte in eigenen Programmen verwendet,
sieht man am Besten an einem Schritt-für-Schritt-Beispiel. Ich habe
mit dem RCT ein Menü und einen Requester entworfen und mit den
folgenden Befehlen kann man sie in ein eigenes Programm einbinden. Die
Datei heißt im Beispiel Req.RCT, man kann sie aber natürlich beliebig
benennen.
1. Mit RCT einen Requester und ein Menü entwerfen und als REQ.RCT
abspeichern. Der RCT erzeugt zwei Dateien: REQ.RCT und REQ.DFN
2. Mit RCT_TO_ASCII C-Quelltext generieren lassen. RCT_TO_ASCII
erzeugt REQ.c und REQ.h. In Req.h stehen die IDs der Gadgets und
Requester.
3. Man schreibt sich ein Modul, in dem man alle '#define'-statements
in REQ.h als Konstanten definiert. Alle Variablen aus REQ.C, auf
die man im Oberon-Programm zugreifen will, müssen in der Form
33name["_cname"]:type31m definiert werden. Dabei ist zu
beachten, daß der C-Compiler vor Variablen und Prozeduren einen
Unterstrich '_' einfügt. Z.B. bekommt die Variable 'reqmenu' aus
dem C-Quelltext das Label '_reqmenu'.
Für jeden entworfenen Requester generiert RCT eine Aufrufprozedur.
Man muß sie als
33mPROCEDURE Name{"label"}(window:LONGINT):LONGINT;31m
definieren. Diese Prozedur kann man dann mit RCT.CCall() aufrufen.
Ein Beispiel für eine solche Datei ist das Modul ReqInterface.
4. Man schreibt sich ein Programm um die definierten Datenstrukturen
zu testen (siehe RCTTest.mod) .
5. Man kompiliert mit einem C-Compiler den C-Quelltext. Z.B.
> 33mdcc -mD -c REQ.c -o obj/REQ.o31m
Die Option '-mD' bewirkt beim DICE, daß das große Datenmodell
(Large-Data) verwendet wird. Das kleine Datenmodell (Small-Data)
ist nicht zum kleinen Datenmodell von Amiga-Oberon kompatibel und
kann deshalb nicht verwendet werden. Dies gilt auch bei Verwendung
anderer C-Compiler wie SAS-C oder North-C (beide nicht getestet).
Aztec-C ist ungeeignet, da der erzeugte Object-Code nicht BLink-
kompatibel ist.
6. Man kompiliert und linkt das ganze Programm. Z.B.
> 33mOMake c-md RCTTest DONTLINK31m
> 33mOLink RCTTest -smd obj obj/Req.o31m
Man muß OLink extra aufrufen, da die C-Objektdatei Req.o von OLink
nicht gefunden wird und deshalb explizit angegeben werden muß.
Das Modul RCT besteht aus einem Oberon und einem Assemblerteil. Im
Assemblerteil werden dem RCT-generierten C-Programm die benötigten
Variablen und Prozeduren zur Verfügung gestellt. Zum Kompilieren bzw.
Assemblieren des Moduls muß man folgende Befehle eingeben:
> 33ma68ktxt/RCT.s -oRAM:RCT.o31m
> 33mOberon -md RCT.mod31m
> 33mJoinobj/RCT.objs RAM:RCT.o as RAM:RCT.objs31m
> 33mCopy RAM:RCT.objs obj31m
Ich habe bei allen Beispielen das kleine Code- und das kleine
Datenmodell gewählt, aber die großen Modelle müßten auch
funktionieren.
Viel Spaß
Volker.